package model

import (
	"ticket/internal/schemas"
	"time"

	"github.com/pkg/errors"
	"gorm.io/gorm"
)

type Task struct {
	ID         uint      `gorm:"column:task_id;primaryKey;autoIncrement" json:"id"`       // 任务id
	Type       uint8     `gorm:"column:task_type;not null;default:0" json:"type"`         // 任务类型： 1-需求 2-缺陷 3-优化 4-其他
	ParentID   uint      `gorm:"column:parent_id;not null;default:0" json:"parent_id"`    // 父任务id
	Name       string    `gorm:"column:task_name;type:varchar(128);not null" json:"name"` // 任务标题
	Describe   string    `gorm:"column:task_describe;type:text;not null" json:"describe"` // 任务描述
	AnnexUrls  string    `gorm:"column:annex_urls;type:varchar(5000)" json:"annex_urls"`  // 附件集合
	ProjectID  uint      `gorm:"column:project_id;not null" json:"project_id"`            // 项目id
	CreatedAt  time.Time `gorm:"column:created_at" json:"created_at"`
	UpdatedAt  time.Time `gorm:"column:updated_at" json:"updated_at"`
	ExpectedAt time.Time `gorm:"column:expected_at" json:"expected_at"`
	CreateBy   string    `gorm:"column:create_by;type:varchar(64)" json:"create_by"`        // 创建者
	UpdateBy   string    `gorm:"column:update_by;type:varchar(64)" json:"update_by"`        // 更新者
	State      uint8     `gorm:"column:state;not null;default:0" json:"state"`              // 任务状态： 1-未开始 2-进行中 3-已完成 4-已暂停 5-已延期 6-已解决
	KeyWords   string    `gorm:"column:key_words;type:varchar(255);index" json:"key_words"` // 任务关键字
	Handlers   []User    `gorm:"many2many:task_users;" json:"handlers"`                     // 处理人
}

// 创建任务，并给TaskLog创建一条日志
func (d *Task) Create(tx *gorm.DB) error {
	// 开始事务
	err := tx.Transaction(func(tx *gorm.DB) error {
		// 创建任务
		if err := tx.Create(d).Error; err != nil {
			return errors.New("创建任务失败")
		}

		// 创建任务日志
		taskLog := TaskLog{
			TaskID:    d.ID,
			UpdatedBy: d.CreateBy,
			Content:   "任务创建",
		}
		if err := tx.Create(&taskLog).Error; err != nil {
			return errors.New("创建任务日志失败")
		}

		return nil
	})

	return err
}

func (d *Task) Update(tx *gorm.DB, fields ...string) error {
	result := tx.Model(d).Select(fields).Updates(d)
	if result.Error != nil {
		return errors.New("更新任务失败")
	}
	return nil
}

func (d *Task) Delete(tx *gorm.DB) error {
	result := tx.Model(d).Delete(d)
	if result.Error != nil {
		return errors.New("删除任务失败")
	}
	return nil
}

func (d *Task) GetByID(tx *gorm.DB, id any) (*Task, error) {
	result := tx.Model(d).First(d, id)
	if result.Error != nil || errors.Is(result.Error, gorm.ErrRecordNotFound) {
		return nil, errors.New("获取任务失败")
	}
	return d, nil
}

func (d *Task) List(tx *gorm.DB, params *schemas.QueryTask) ([]*Task, error) {
	var tasks []*Task
	tx = tx.Model(d)
	if params.Name != "" {
		tx = tx.Where("name LIKE ?", "%"+params.Name+"%")
	}
	if params.ParentID != 0 {
		tx = tx.Where("parent_id = ?", params.ParentID)
	}
	if params.CreateBy != "" {
		tx = tx.Where("create_by = ?", params.CreateBy)
	}
	if params.Handlers != nil {
		tx = tx.Where("handlers IN (?)", params.Handlers)
	}
	if params.ProjectID != 0 {
		tx = tx.Where("project_id = ?", params.ProjectID)
	}
	if params.State != 0 {
		tx = tx.Where("state = ?", params.State)
	}
	tx.Offset((params.Page - 1) * params.PageSize).Limit(params.PageSize).Find(&tasks)
	return tasks, nil
}
